package com.benyi.util;


import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.security.MessageDigest; 
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import java.util.Calendar;
import java.util.Date;
import java.util.List; 

public class Tools {
	private static final String CPathFlag="classpath:";
	
	private static final char[] HexDigit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
			'A', 'B', 'C', 'D', 'E', 'F' }; 
	
	private static final char SPACE_C=0x3000; //中文空格
	private static final char SPACE_E=0x20;   //英文空格
	
	public static int toInteger(String s) {
		int l=0;
		if(s==null || s.length()==0) {
			return l;
		}
		for(int i=0;i<s.length();i++) {
			l=l*10+s.charAt(i);
		}
		return l;
	}
	
	public static String byteToStr(byte[] byteArray) {
		StringBuilder sb=new StringBuilder();
		for (int i = 0; i < byteArray.length; i++) {
			sb.append(byteToHexStr(byteArray[i]));
		}
		return sb.toString();
	}

	public static String byteToHexStr(byte mByte) { 
		
		char[] tempArr = new char[2]; 
		tempArr[0] = HexDigit[(mByte >>> 4) & 0X0F]; 
		tempArr[1] = HexDigit[mByte & 0X0F]; 
		String s = new String(tempArr); 
		return s; 
	} 
	
	public static String md5(String v){
		String r=null;
		try{
			MessageDigest md5=MessageDigest.getInstance("MD5");
			byte []b=md5.digest(v.getBytes("utf-8")); 
			r=byteToStr(b);
			return r;
		}catch(Exception e){
			e.printStackTrace();
		}
		return r;
	}
	
	public static String base64(byte []b){
		Encoder ec=Base64.getEncoder();
		byte[] v=ec.encode(b);
		String s=new String(v);
		return s;
	}
	
	public static String toBase64(String str){
		if(str==null || str.length() < 1) {
			return str;
		}
		Encoder ec=Base64.getEncoder();
		try {
			byte []b=str.getBytes("utf-8");
			byte[] v=ec.encode(b);
			String s=new String(v,"utf-8");
			return s;
		}catch(Exception e) {
			e.printStackTrace();
		}
		return str;
	}
	
	public static String fromBase64(String str){
		if(str==null || str.length() < 1) {
			return str;
		}
		Decoder dc=Base64.getDecoder();
		try {
			byte []b=dc.decode(str.getBytes("utf-8")); 
			String s=new String(b,"utf-8");
			return s;
		}catch(Exception e) {
			e.printStackTrace();
		}
		return str;
	}
	
	public static String toString(String[] ls,String sp) {
		StringBuilder sb=new StringBuilder();
		if(ls==null) {
			return "";
		}
		sb.append("[");
		for(int i=0;i<ls.length;i++) {
			if(Tools.isEmpty(ls[i])) {
				continue;
			}
			if(i>0) {
				sb.append(sp);
			}
			sb.append(ls[i]);
		}
		sb.append("]");
		return sb.toString();
	}
	
	public static String toString(Object obj) {
		
		if(obj==null){
			return "null";
		}
		
		StringBuffer strBuf = new StringBuffer();
		Class<?> cla = obj.getClass(); 
		
		/**
		 * 对于基本数据类型和String直接返回
		 */
		if (cla == Integer.class || cla == Short.class || cla == Byte.class || cla == Long.class || cla == Double.class
				|| cla == Float.class || cla == Boolean.class || cla == String.class 
				|| cla == Character.class || cla==Byte.class || cla==java.util.Date.class
				|| cla==java.sql.Date.class || cla==java.math.BigDecimal.class) {
			strBuf.append(obj);
			return strBuf.toString();
		}

		/**
		 * 对数组类型的处理
		 */
		if (cla.isArray()) { 
			int len=Array.getLength(obj); 
			strBuf.append("[");
			for (int i = 0; i < len; i++) {
				if (i > 0){
					strBuf.append(",");
				}
				Object val = Array.get(obj, i);
				if (val != null && !val.equals("")) {
					strBuf.append(toString(val));
				}
			}
			strBuf.append("]");
			return strBuf.toString();
		}
		
		if (List.class.isInstance(obj)){
			List<?> ls=(List<?>)(obj);
			int len=ls.size(); 
			strBuf.append("[");
			for (int i = 0; i < len; i++) {
				if (i > 0){
					strBuf.append(",");
				}
				Object val = ls.get(i);
				if (val != null && !val.equals("")) {
					strBuf.append(toString(val));
				}
			}
			strBuf.append("]");
			return strBuf.toString();
		}

		// 获取所有属性
		Field[] fields = cla.getDeclaredFields();

		// 设置所有属性方法可访问
		AccessibleObject.setAccessible(fields, true);

		strBuf.append("{");
		for (int i = 0; i < fields.length; i++) { 
			Field fd = fields[i];
			if( Modifier.isStatic(fd.getModifiers()) || Modifier.isFinal(fd.getModifiers()) ){
				continue; //static, final 的忽略
			}
			strBuf.append(fd.getName() + "=");
			try {
				if ( fd.getType().isPrimitive() || fd.getType() == String.class) {
					strBuf.append(fd.get(obj));					
				} else {
					strBuf.append(toString(fd.get(obj)));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (i != fields.length - 1){
				strBuf.append(",");
			}
		}

		strBuf.append("}");
		return strBuf.toString();
	}
	
	public static boolean equals(String v1,String v2){
		if(v1==null && v2==null){
			return true;
		}
		if(v1==null){
			if(v2.length()==0){
				return true;
			}else{
				return false;
			} 
		}
		if(v2==null){
			if(v1.length()==0){
				return true;
			}else{
				return false;
			}			
		}
		if(v1.equals(v2)){
			return true;
		}
		return false;
	}

	public static boolean isEmpty(String s){
		if(s==null){
			return true;
		}
		s=trim(s);
		if(s.length()==0){
			return true;
		}
		return false;
	}

	public static boolean existFile(String dir ,String file){
		File f=new File(dir,file);
		if(f.exists()){
			return true;
		}
		return false;
	}
	
	public static String replace(String v,String r,String n) {
		if(v==null || r==null || n==null ) return v;
		int index=v.indexOf(r);
		String nv=v;
		while(index>=0) { 
			nv=v.substring(0, index)+n+v.substring(index+r.length());
			v=nv;
			index=v.indexOf(r);
		}
		return nv;
	}
	
	public static String replaceFirst(String v,String r,String n,int[] from) {
		if(v==null || r==null || n==null ) return v;
		int f=v.indexOf(r,from[0]);
		if(f<from[0]) {
			return v;
		}
		from[0]=f+n.length();
		return v.substring(0,f)+n+v.substring(f+r.length());
	}
	
	public static String replaceBrace(String v,Object ...p) {
		if(v==null || p==null ) return v;
		String s=v;
		String one; 
		int []op= {0};
		for(int i=0;i<p.length;i++) {
			if(p[i]==null) {
				one="null";
			}else {
				//one=JsonTool.toString(p[i]);
				one = toString(p[i]);
				if(one!=null && one.equals("{}")) {
					one = p[i].toString();
				}
				if(one.startsWith("\"") && one.endsWith("\"")) {
					one = one.substring(1, one.length()-1);
				}
			}
			s=replaceFirst(s, "{}", one, op); 
		}
		return s;
	}
	
	public static String readTextFile(String file) throws Exception { 
		InputStreamReader reader=null;
		StringBuilder sb=new StringBuilder();
		if(file.startsWith(CPathFlag)){
    		file=file.substring(CPathFlag.length()); 
    		ClassLoader loader=Tools.class.getClassLoader(); 
			InputStream is=loader.getResourceAsStream(file);  
			reader = new InputStreamReader(is, "UTF-8");  
    	}else{ 
    		reader = new InputStreamReader(new FileInputStream(file), "UTF-8");  
    	} 
    	int c=reader.read();
    	while(c!=-1) {
    		sb.append((char)c);
    		c=reader.read();
    	}
    	reader.close();
    	return sb.toString();
	}
	
	public static String format(Date t,int f) {
		DateFormat df = null;
		if(t==null) {
			return "";
		}
		if(f==0) {
			df = new SimpleDateFormat("yyyy年M月d日");
		}else
		if(f==1) {
			df = new SimpleDateFormat("yyyy年M月d日H时m分");
		}else
		if(f==2) {
			df = new SimpleDateFormat("yyyy年M月d日H时m分s秒");
		}else
		if(f==3) {
			df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		}
		
		if(df==null) {
			df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		}
		String ts = df.format(t.getTime());
		return ts;
	}
	
	public static String getTimeStamp(int amount) {
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
		Calendar c = Calendar.getInstance();
		c.add(Calendar.SECOND, amount);
		String ts = df.format(c.getTime());
		return ts;
	}
	
	public static String getTimeStampMms(int amount) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar c = Calendar.getInstance();
		c.add(Calendar.SECOND, amount);
		String ts = df.format(c.getTime());
		long nm=System.currentTimeMillis()%1000; 
		return ts+"."+String.valueOf(nm);
	} 
	 
	public static String dateToString(Date d) {
		if(d==null) {
			return null;
		}
		SimpleDateFormat f=new SimpleDateFormat("yyyy年M月d日 H时m分");
		String s=f.format(d);
		return s;
	}
	
	public static String dateToString(Date d,String tips) {
		if(d==null) {
			return tips;
		}
		SimpleDateFormat f=new SimpleDateFormat("yyyy年M月d日 H时m分");
		String s=f.format(d);
		return s;
	}
	
	public static String dateToStamp(Date d) {
		if(d==null) {
			return null;
		}
		SimpleDateFormat f=new SimpleDateFormat("yy/MM/dd HH:mm");
		String s=f.format(d);
		return s;
	}
	
	public static String toDay(Date d) {
		if(d==null) {
			return null;
		}
		SimpleDateFormat f=new SimpleDateFormat("yyyy年M月d日");
		String s=f.format(d);
		return s;
	}
	
	public static String toDayEn(Date d) {
		if(d==null) {
			return null;
		}
		SimpleDateFormat f=new SimpleDateFormat("yyyy-MM-dd");
		String s=f.format(d);
		return s;
	}
	
	public static boolean isExpired(String tm) {
    	String c=Tools.getTimeStamp(0);
    	if(c.compareTo(tm)>=0) {
    		return false;
    	}
    	return true;
    }
	
	public static boolean isNumber(String v) {
		if(v==null || v.length()<1) {
			return false;
		}
		int i=0;
		char c;
		while(i<v.length()) {
			c=v.charAt(i);
			if(c<'0' || c>'9') {
				return false;
			}
			i++;
		}
		return true;
	}
	
	public static int[] parseIntArray(String str,String sp) {
		if(str==null || str.length()==0) {
    		return new int[0];
    	}
    	ArrayList<Integer> ids = new ArrayList<Integer>();
    	String []ds = str.split(sp);
    	for(int i=0;i<ds.length;i++) {
    		if(Tools.isNumber(ds[i]) == false) {
    			continue;
    		}
    		Integer n = Integer.parseInt(ds[i]);
    		ids.add(n);
    	}
    	int []t = new int[ids.size()];
    	for(int i=0;i<t.length;i++) {
    		t[i] = ids.get(i).intValue();
    	}
    	return t;
	}
	
	public static String updateString(String vs,String item,int op,String sep) {
    	if(Tools.isEmpty(item)) {
    		return vs;
    	}
    	if( !(op==0 || op==1) ) {
    		return vs;
    	}
    	String s=vs;
    	if(op==1) {
			if(Tools.isEmpty(s)) {
				s=item;
			}else {
				if(s.indexOf(item)<0) {
					s=s+","+item;
				} 
			}
		}
    	if(op==0) {
			if(Tools.isEmpty(s)==false) {
				String []sl=s.split(sep);
				for(int i=0;i<sl.length;i++) {
					if(item.equals(sl[i])) {
						sl[i]=null;
						break;
					}
				}
				s=Tools.toString(sl,",");
			}
		} 
    	return s;
    }
	
	public static String invalidScript(String s) {
		if(s==null) return s;
		char c1='<';
		char c2='>';
		String s1="&lt;";
		String s2="&gt;";
		s=s.replace(String.valueOf(c1), s1);
		s=s.replace(String.valueOf(c2), s2);
		return s;
	}
	
	/**
	   *   防止 脚本注入
	 * @param obj
	 */
	public static void invalidScript(Object obj) {
		if(obj==null) {
			return ;
		}
		Field []fs=obj.getClass().getDeclaredFields();
		for(int i=0;i<fs.length;i++) {
			Field f=fs[i];
			if(f.getType() != String.class) {
				continue;
			}
			try {
				f.setAccessible(true);
				String v=(String)f.get(obj);
				if(v!=null) {
					v=invalidScript(v); 
					f.set(obj, v);
				}
			}catch(Exception e) {
				e.printStackTrace();
			} 
		} 
	}
	
	public static <T> T copyNotNullFields(T obj,T src) {
		if(obj==null || src ==null) {
			return obj;
		}
		 
		Field []fs=obj.getClass().getDeclaredFields();
		for(int i=0;i<fs.length;i++) {
			Field f=fs[i]; 
			try {
				f.setAccessible(true);
				Object v=f.get(src);
				if(v!=null) {
					f.set(obj, v); 
				} 
			}catch(Exception e) {
				e.printStackTrace();
			} 
		} 
		return obj;
	}
	
	public static void setNull(Object obj) {
		if(obj==null) {
			return ;
		}
		Field []fs=obj.getClass().getDeclaredFields();
		for(int i=0;i<fs.length;i++) {
			Field f=fs[i]; 
			try {
				f.setAccessible(true);
				f.set(obj, null); 
			}catch(Exception e) {
				e.printStackTrace();
			} 
		} 
	}
	
	public static void trim(Object obj) {
		if(obj==null) {
			return ;
		}
		Field []fs=obj.getClass().getDeclaredFields();
		for(int i=0;i<fs.length;i++) {
			Field f=fs[i];
			if(f.getType() != String.class) {
				continue;
			}
			try {
				f.setAccessible(true);
				String v=(String)f.get(obj);
				if(v!=null) {
					v=trim(v); 
					f.set(obj, v);
				}
			}catch(Exception e) {
				e.printStackTrace();
			} 
		} 
	}
	
	public static String trim(String m) { 
		if(m==null || m.length()==0) {
			return m;
		}
		String n=m;
		int len=n.length();
		int to=0;
		while(to<len) {
			char d=n.charAt(to);
			if(d==SPACE_E || d==SPACE_C) {
				to++;
			}else {
				break;
			}
		}
		if(to>0) {
			n=n.substring(to);
		}
	 
		to=n.length()-1;
		while(to>=0) {
			char d=n.charAt(to); 
			if(d==SPACE_E || d==SPACE_C) {
				to--;
			}else {
				break;
			}
		}
		if(to<0) {
			return "";
			
		}else {
			return n.substring(0, to+1);
		}  
	}
	
	public static BigDecimal toDecimal(int v) {
		String s = String.valueOf(v/100)+"."+String.valueOf(v%100);
		BigDecimal d=new BigDecimal(s);
		return d;
	}
	
	public static boolean isExpired(Date from, Date to) {
		if (from == null) {
			if (to == null) {
				return false;
			} else {
				if (to.compareTo(new Date()) >= 0) {
					return false;
				}
				return true;
			}
		}
		if (from.compareTo(new Date()) > 0) {
			return true; 
		} 

		if (to == null) {
			return false;
		} else {
			if (to.compareTo(new Date()) >= 0) {
				return false;
			}
			return true;
		} 
	}
	
	public static boolean isToday(Date t) {
		if(t==null) {
			return false;
		}
		Calendar c = Calendar.getInstance();
		int y = c.get(Calendar.YEAR);
		int d = c.get(Calendar.DAY_OF_YEAR);
		
		c.setTime(t);
		
		int y1 = c.get(Calendar.YEAR);
		int d1 = c.get(Calendar.DAY_OF_YEAR);
		
		if(y == y1 && d == d1) {
			return true;
		}
		return false;
	}
	
	
	public static String g2u(String s) {
		if(s==null) return null;
		try {
			byte []b=s.getBytes("GBK");
			return new String(b,"utf-8");
		}catch(Exception e) {
			//
		}
		return s;
	}
	
	public static String a2u(String s) {
		if(s==null) return null;
		try {
			byte []b=s.getBytes("1so8859-1");
			return new String(b,"utf-8");
		}catch(Exception e) {
			//
		}
		return s;
	}
	
	public static String getTraceMsg(Exception e) { 
		StringWriter sw=new StringWriter();
		PrintWriter pw = new PrintWriter(sw);  
		e.printStackTrace(pw); 
		String msg = sw.toString(); 
		pw.close(); 
		return msg;
	} 
	
	public static String toString(int []v) {
		if(v==null) {
			return null;
		}
		if(v.length==0) {
			return "";
		}
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<v.length; i++) {
			if(i>0) {
				sb.append(",");
			}
			sb.append(v[i]);
		} 
		String s = sb.toString();
		sb = null;
		return s;
	}
	
	public static String toString(List<Integer> v) {
		if(v==null) {
			return null;
		}
		if(v.size()==0) {
			return "";
		}
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<v.size(); i++) {
			if(i>0) {
				sb.append(",");
			}
			sb.append(v.get(i));
		}
		String s = sb.toString();
		sb = null;
		return s;
	}
	
	public static void main(String []args) throws Exception { 
		long t = System.currentTimeMillis();
		
		String o="this is {},and he is {} years old ,birthday is {},score list is {}";
		 
		String s = replaceBrace(o,"tom",1,3,4);
		
		t = System.currentTimeMillis() - t;
		System.out.println(s+","+t);  
		
		t = System.currentTimeMillis(); 
		s = replaceBrace(o,"Tom",30,new Date(),"Cat",101,102);
		
		t = System.currentTimeMillis() - t;
		System.out.println(s+","+t);  
		
	}
}

